/**************************************************************************************
*  Rgb.java
*  Program demonstrating the use of PWMs with LPC21xx to control tri-color LED.
**************************************************************************************
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Created by:
*      RTJ Computing
**************************************************************************************/
import lpc2xxx.edu.*;
import lpc2xxx.hw.*;
import javax.events.*;


class Rgb
{
    // duty is controlled in 0.01% increments
    final static String[] colors = { "Red   ", "Blue  ", "Green " };
    final static int max = 10000;
    static int col = 0;
    static Switch sw = new Switch();
    static int freq = 100;
    
    static Events ev = new Events();
    static Timer tmr = new Timer();
    static RgbDemo demo = new RgbDemo();

    static void main(String[] args) 
    {
        Console.println("");
        Console.println("LPC21xx RGB LED control with PWM2/4/6");
        Console.println("This program is for use with LPC2148 Education board");
        Console.println("Jumper settings:");
        Console.println("  disconnect J49,J51,J53");
        Console.println("  connect    J34,J35,J36\r\n");
        Console.println("Press joystick - left/right to change active color intensity");
        Console.println("               - up/down to activate next color");
        Console.println("To exit press ESC");
        Console.println("");

        try 
        {
            tmr.addHandler(demo);
            ev.addEvent(tmr, 0);
            ev.start();
        }
        catch (Exception e)
        {
            Console.println("Events exception " + e.getMessage());
            return;
        }
        resetDemoTimer();
        
        sw.start();

        int[] duty = new int[3];
        PWM.init(PWM.PWM2 | PWM.PWM4 | PWM.PWM6, freq);
        setDuty(duty);
        while (true)
        {
            if (Console.getKey() == Console.ESC)
                break;

            int pCol = col;
            if (sw.up())
            {
                if (--col < 0)
                    col = 2;
            }
            else if (sw.down())
            {
                if (++col > 2)
                    col = 0;
            }
            if (pCol != col)
            {
                setDuty(duty);
                while (sw.up() || sw.down())
                    Thread.yield();
            }

            int newDuty = duty[col];
            if (sw.left() && duty[col] > 0)
                newDuty -= 500;
            else if (sw.right() && duty[col] < max)
                newDuty += 500;

            if (newDuty != duty[col])
            {
                duty[col] = newDuty;
                setDuty(duty);
                sleep(200);
                resetDemoTimer();
            }

        }
        duty[0] = duty[1] = duty[2] = 0;
        setDuty(duty);
    }

    static void setDuty(int[] duty)
    {
        PWM.duty(PWM.PWM2, duty[0]);
        PWM.duty(PWM.PWM4, duty[1]);
        PWM.duty(PWM.PWM6, duty[2]);
        PWM.apply();

        int perc = duty[col] / 100;
        Console.print("\r" + colors[col] + Integer.toString(perc) + "%  ");
    }

    static void sleep(int ms)
    {
        try 
        { 
            Thread.sleep(ms); 
        } 
        catch (InterruptedException e) {}
    }

    static void resetDemoTimer()
    {
        tmr.start(demo, 20000);
    }

    static void setDemoDuty(int r, int b, int g)
    {
        PWM.duty(PWM.PWM2, r);
        PWM.duty(PWM.PWM4, b);
        PWM.duty(PWM.PWM6, g);
        PWM.apply();
    }

    static void runDemo()
    {
        int r, g, b;
        while (!sw.keyDown())
        {       
            for (int i=5; i < 15 && !sw.keyDown(); i++)
            {
                // red
                b = g = 0;
                for (r=0; r < max && !sw.keyDown(); r += 100)
                {
                    setDemoDuty(r, b, g);
                    sleep(i);
                }
                g = b = 0;
                for (r=max; r >= 0 && !sw.keyDown(); r -= 100)
                {
                    setDemoDuty(r, b, g);
                    sleep(i);
                }
                // blue
                r = g = 0;
                for (b=0; b < max && !sw.keyDown(); b += 100)
                {
                    setDemoDuty(r, b, g);
                    sleep(i);
                }
                r = g = 0;
                for (b=max; b >= 0 && !sw.keyDown(); b -= 100)
                {
                    setDemoDuty(r, b, g);
                    sleep(i);
                }
                // green
                r = b = 0;
                for (g=0; g < max && !sw.keyDown(); g += 100)
                {
                    setDemoDuty(r, b, g);
                    sleep(i);
                }
                r = b = 0;
                for (g=max; g >= 0 && !sw.keyDown(); g -= 100)
                {
                    setDemoDuty(r, b, g);
                    sleep(i);
                }
            }
        }
    }
}

class RgbDemo extends OneShotTimerHandler
{
    RgbDemo()
    {
    }

    public void handleAsyncEvent()
    {
        Rgb.runDemo();
    }
}
